using System;
using System.Collections.Generic;
using System.Text;

namespace Decav.Gatsb
{
    /// <summary>
    /// Provides string format helper utilities.
    /// </summary>
    public static class StringFormatting
    {
        /// <summary>
        /// Reformats plain text into HTML, changing things such as carridge return, line feed into BR and P tags.
        /// </summary>
        /// <param name="plainText">The text to format.</param>
        /// <returns>The HTML formatted text.</returns>
        public static string PlainTextToHtml(string plainText)
        {
            if (plainText == null)
                return null;

            return plainText.Replace("\r\n", "<br/>");
        }

        /// <summary>
        /// Gets the time as how many days, minutes or hours ago the time was.
        /// </summary>
        /// <param name="time">The time to look at.</param>
        /// <returns>The string such as '20 minutes ago'.</returns>
        public static string ToTimeAgo(DateTime time)
        {
            TimeSpan timeAgo = DateTime.UtcNow - time;

            if (timeAgo.TotalMinutes < 5)
                return "a few minutes ago";
            else if (timeAgo.TotalMinutes < 50)
                return string.Format("{0} minutes ago", (int)Math.Round(timeAgo.TotalMinutes));
            else if (timeAgo.TotalMinutes < 90)
                return "an hour ago";
            else if (timeAgo.TotalMinutes < 105)
                return "an hour and a half ago";
            else if (timeAgo.TotalHours < 18)
            {
                int hours = (int)Math.Floor(timeAgo.TotalHours);
                double remainder = timeAgo.TotalHours - hours;

                if (remainder < .4)
                    return string.Format("{0} hours ago", hours);
                else if (remainder >= .3 && remainder <= .7)
                    return string.Format("{0} and a half hours ago", hours);
                else
                    return string.Format("{0} hours ago", hours + 1);

            }
            else if (timeAgo.TotalHours < 28)
                return "a day ago";
            else if (timeAgo.TotalDays < 1.7)
                return "a day and a half ago";
            else if (timeAgo.TotalDays < 6.5)
            {
                // calculate days
                int days = (int)Math.Floor(timeAgo.TotalDays);
                double remainder = timeAgo.TotalDays - days;

                if (remainder < .4)
                    return string.Format("{0} days ago", days);
                else if (remainder >= .3 && remainder <= .7)
                    return string.Format("{0} and a half days ago", days);
                else
                    return string.Format("{0} days ago", days + 1);
            }
            else if (timeAgo.TotalDays < 9)
                return "a week ago";
            else if (timeAgo.TotalDays < 25)
            {
                // calculate weeks
                int weeks = (int)Math.Floor(timeAgo.TotalDays / 7.0);
                double remainder = timeAgo.TotalDays / 7.0 - weeks;

                if (remainder < .4)
                    return string.Format("{0} weeks ago", weeks);
                else if (remainder >= .3 && remainder <= .7)
                    return string.Format("{0} and a half weeks ago", weeks);
                else
                    return string.Format("{0} weeks ago", weeks + 1);
            }
            else if (timeAgo.TotalDays < 365)
            {
                // Calculate months
                int months = (int)Math.Floor(timeAgo.TotalDays / 30.5);
                double remainder = timeAgo.TotalDays / 30.5 - months;

                if (remainder < .4)
                    return string.Format("{0} months ago", months);
                else if (remainder >= .3 && remainder <= .7)
                    return string.Format("{0} and a half months ago", months);
                else
                    return string.Format("{0} months ago", months + 1);
            }
            else
            {
                // calclulate years
                return "a long time ago";
            }
        }

        /// <summary>
        /// Returns a friendly date name such as "today" or "yesterday" for a date.
        /// </summary>
        /// <param name="date">The date to get the friendly name for, in UTC.</param>
        /// <returns>The string format for the date.</returns>
        public static string ToFriendlyDate(DateTime date)
        {
            DateTime dateUtc = DateTime.UtcNow.Date;
            TimeSpan timeSince = dateUtc - date;

            if (date == dateUtc)
                return "Today";
            else if (date == dateUtc.AddDays(-1))
                return "Yesterday";
            else if (timeSince.TotalDays < 7)
                return date.DayOfWeek.ToString();
            else if (timeSince.TotalDays < 14)
                return string.Format("{0} days ago", (int)Math.Floor(timeSince.TotalDays));
            else if (timeSince.TotalDays < 45)
                return string.Format("{0} weeks ago", (int)Math.Floor(timeSince.TotalDays / 7));
            else if (timeSince.TotalDays < 365)
                return string.Format("{0} months ago", (int)Math.Floor(timeSince.TotalDays / 30.5));
            else
                return "a long time ago";
        }
    }
}
